﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Xml.Linq;
using Puzzler.Common;
using Puzzler.Plugin.Interface;
using Puzzler.Plugin.Interface.Attributes;

namespace Plugin.Default.SwedenGrid
{
    [PuzzleIOHandler]
    public sealed class SwedenGridIOHandler : GridPuzzleIOHandler<SwedenGridModel,SwedenGridCellInfo,SwedenGridIOUpgrateHandler>
    {
        private static readonly BrushConverter BrushConverter = new BrushConverter();

        public override int XmlFormatVersion
        {
            get { return 1; }
        }

        public override int BinaryFormatVersion
        {
            get { return 1; }
        }

        public SwedenGridIOHandler(SwedenGridModel model) : base(model)
        {
        }

        #region XML

        protected override void SaveSettingsToXElement(XElement xElement)
        {
            XElement color = new XElement("Colors");
            color.Add(new XAttribute("regular-text", BrushConverter.ConvertToString(Model.ColorModel.RegularText)));
            color.Add(new XAttribute("regular-background", BrushConverter.ConvertToString(Model.ColorModel.RegularBackground)));
            color.Add(new XAttribute("regular-border", BrushConverter.ConvertToString(Model.ColorModel.RegularBorder)));

            color.Add(new XAttribute("question-text", BrushConverter.ConvertToString(Model.ColorModel.QuestionText)));
            color.Add(new XAttribute("question-background", BrushConverter.ConvertToString(Model.ColorModel.QuestionBackground)));
            color.Add(new XAttribute("question-border", BrushConverter.ConvertToString(Model.ColorModel.QuestionBorder)));

            xElement.Add(color);
        }

        protected override void LoadSettingsFromXElement(XElement xElement)
        {
            XElement color = xElement.ReadFromElement("Colors");
            Model.ColorModel = new SwedenGridColorModel
            {
                RegularText = color.ReadFromAttribute(
                    "regular-text", s => (Brush)BrushConverter.ConvertFromString(s)),
                RegularBorder = color.ReadFromAttribute(
                    "regular-border", s =>
                                      (Brush)BrushConverter.ConvertFromString(s)),
                RegularBackground = color.ReadFromAttribute(
                    "regular-background", s => (Brush)BrushConverter.ConvertFromString(s)),
                QuestionText = color.ReadFromAttribute(
                    "question-text", s => (Brush)BrushConverter.ConvertFromString(s)),
                QuestionBorder = color.ReadFromAttribute(
                    "question-border", s => (Brush)BrushConverter.ConvertFromString(s)),
                QuestionBackground = color.ReadFromAttribute(
                    "question-background", s => (Brush)BrushConverter.ConvertFromString(s))
            };
        }

        protected override void SaveCellInfoToXElemenmt(SwedenGridCellInfo info, XElement element)
        {
            element.Add(new XAttribute(SwedenGridCellInfo.ShowAlwaysProperty.Name, info.ShowAlways));
            element.Add(new XAttribute(SwedenGridCellInfo.CellTypeProperty.Name, info.CellType));

            XElement content = new XElement(SwedenGridCellInfo.CellContentProperty.Name);
            SaveCellContentToXElement(info.CellContent, content);
            element.Add(content);

            if (info.AdditionalCellContent != null)
            {
                XElement additionalContent = new XElement(SwedenGridCellInfo.AdditionalCellContentProperty.Name);
                SaveCellContentToXElement(info.AdditionalCellContent, additionalContent);
                element.Add(additionalContent);
            }
        }

        protected override void LoadCellInfoFromXElement(SwedenGridCellInfo info, XElement element)
        {
            info.ShowAlways = element.ReadFromAttribute(SwedenGridCellInfo.ShowAlwaysProperty.Name, Boolean.Parse);
            info.CellType = element.ReadFromAttribute(SwedenGridCellInfo.CellTypeProperty.Name,
                s => (SwedenGridCellType)Enum.Parse(typeof(SwedenGridCellType), s));

            XElement content = element.ReadFromElement(SwedenGridCellInfo.CellContentProperty.Name);
            info.CellContent = new SwedenGridCellContent();
            LoadCellContentFromXElement(info.CellContent, content);

            XElement additionalContent = element.Element(SwedenGridCellInfo.AdditionalCellContentProperty.Name);
            if (additionalContent != null)
            {
                info.AdditionalCellContent = new SwedenGridCellContent();
                LoadCellContentFromXElement(info.AdditionalCellContent, additionalContent);
            }
        }

        private void SaveCellContentToXElement(SwedenGridCellContent cellContent, XElement element)
        {
            element.Add(new XAttribute(SwedenGridCellContent.CellDirectionProperty.Name, cellContent.CellDirection));
            element.Add(new XAttribute(SwedenGridCellContent.TextProperty.Name, cellContent.Text));
        }

        private void LoadCellContentFromXElement(SwedenGridCellContent cellContent, XElement element)
        {
            cellContent.CellDirection = element.ReadFromAttribute(SwedenGridCellContent.CellDirectionProperty.Name,
                s => (SwedenGridCellDirection)Enum.Parse(typeof(SwedenGridCellDirection), s));
            cellContent.Text = element.ReadFromAttribute(SwedenGridCellContent.TextProperty.Name, s => s);
        }

        #endregion
    }
}
